package atom.core0.object;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import atom.core0.exception.BizSysException;

public class ObjectUtil {
	

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		List list = new ArrayList();

		list.add("Hello World.");

		System.out.println(getObjectLen(list));
		byte[] aa = object2Bytes(list);
		Object a = bytes2Object(aa);
		System.out.println(a);
	}

	public static int getObjectLen(Object object) throws Exception {

		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		ObjectOutputStream oos = new ObjectOutputStream(baos);

		oos.writeObject(object);

		byte[] bs = baos.toByteArray();

		// 对象的大小

		int size = bs.length - 4;
		return size;
	}

	
	public static byte[] object2Bytes(Object object) throws BizSysException{

		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();

			ObjectOutputStream oos = new ObjectOutputStream(baos);

			oos.writeObject(object);

			byte[] bs = baos.toByteArray();

			return bs;
		} catch (Exception e) {
			throw new BizSysException(e,"object2Bytes转换失败");
			
		}
	}

	public static Object bytes2Object(byte[] bytes) throws BizSysException {

		try {
			ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
			ObjectInputStream is = new ObjectInputStream(bai);

			Object object = is.readObject();
			return object;
		} catch (Exception e) {
			throw new BizSysException(e,"bytes2Object转换失败");
			
		}

	}

	private static String FormatString(String targetStr, int strLength) {
		int curLength = targetStr.getBytes().length;
		if (targetStr != null && curLength > strLength) {
			targetStr = targetStr.substring(0, strLength);
		}
		String newString = "";
		int cutLength = strLength - targetStr.getBytes().length;
		for (int i = 0; i < cutLength; i++)
			newString += " ";
		return targetStr + newString;
	}

	/**
	 * 
	 * @param entity
	 * @return 获取对象所有属性名称及值
	 * @throws Exception
	 */
	private static String getPropertyString(int i, Class<?> c, Object entityName) throws Exception {
		// Class c = entityName.getClass();
		String className = c.getName();
		Field field[] = c.getDeclaredFields();
		StringBuffer sb = new StringBuffer();
		String space = "";
		space = FormatString(space, i);
		sb.append("\n" + space + className + " 〖Begin〗 \n");
		for (Field f : field) {
			f.setAccessible(true);
			if (isBaseClass(f.getType())) {
				sb.append(space + f.getName());
				sb.append(" : ");
				sb.append(f.get(entityName));
				sb.append("\n");
			} else {
				String name = f.getName();
				String firstLetter = name.substring(0, 1).toUpperCase();
				String getMethodName = "get" + firstLetter + name.substring(1);
				Method getMethod = c.getMethod(getMethodName, new Class[] {});
				Object value = getMethod.invoke(entityName, new Object[] {});
				if (value != null) {
					sb.append(getPropertyString(i + 1, value.getClass(), value));
					sb.append("\n");
				} else {
					sb.append(space + f.getName());
					sb.append(" : ");
					sb.append(f.get(entityName));
					sb.append("\n");
				}
			}
		}
		sb.append(space + className + " 〖End〗");
		if (c.getSuperclass() == null || c.getSuperclass() == java.io.Serializable.class
				|| c.getSuperclass() == java.lang.Object.class)
			return sb.toString();
		sb.append(getPropertyString(i, c.getSuperclass(), entityName));
		return sb.toString();
	}

	private static boolean isBaseClass(Class<?> c) {
		if (c.isPrimitive() || c.getPackage().getName().equals("java.lang")
				|| c.getPackage().getName().equals("java.util"))
			return true;
		else
			return false;
	}

	public static String returnCollectionPropertyString(Collection<?> collection) {
		StringBuffer s = new StringBuffer();
		for (Iterator<?> iterator = collection.iterator(); iterator.hasNext();) {
			Object object = (Object) iterator.next();
			s.append("\n--------------------------------------------------------------------------------");
			s.append("             ").append(returnPropertyString(object));
		}
		return s.toString();
	}

	public static String returnPropertyString(Object object) {
		try {
			if (object == null) {
				return "Object is NULL.";
			}
			String beanToString = ObjectUtil.getPropertyString(13, object.getClass(), object);
			return beanToString;
		} catch (Exception e) {
			return "Read object properties error.";
		}
	}

	public static List<String> getMethodNameList(Object object, String prefix) {
		Class classType = object.getClass();
		return ClassUtil.getMethodNameList(classType, prefix);
	}
}
